﻿using IOP.Orleans.MessageHub;
using Microsoft.Extensions.Logging;
using Orleans;
using System.Threading.Tasks;
using System.Threading;
using System;
using System.Collections.Generic;

namespace IOP.Orleans.Server.MessageHub
{
    /// <summary>
    /// 消息节点
    /// </summary>
    /// <typeparam name="TMessage"></typeparam>
    public class MessageGrain<TMessage> : Grain, IMessageGrain<TMessage>
        where TMessage : class
    {
        /// <summary>
        /// 日志
        /// </summary>
        private readonly ILogger<MessageGrain<TMessage>> _Logger;
        /// <summary>
        /// 监听者管理器
        /// </summary>
        private ObserverManager<IMessageObserver<TMessage>> _ObserverMessage { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger"></param>
        public MessageGrain(ILogger<MessageGrain<TMessage>> logger)
        {
            _Logger = logger;
        }
        /// <summary>
        /// 当此节点被激活时
        /// </summary>
        /// <returns></returns>
        public override Task OnActivateAsync()
        {
            _ObserverMessage = new ObserverManager<IMessageObserver<TMessage>>(_Logger, nameof(TMessage));
            return base.OnActivateAsync();
        }
        /// <summary>
        /// 当被销毁时
        /// </summary>
        /// <returns></returns>
        public override Task OnDeactivateAsync()
        {
            _ObserverMessage.Clear();
            return base.OnDeactivateAsync();
        }
        /// <summary>
        /// 发送消息，并发往指定监听者(通常是除了发布者自己之外的监听者)
        /// </summary>
        /// <param name="message"></param>
        public Task SendMessage(TMessage message, IMessageObserver<TMessage>[] targetObserver = null)
        {
            _ObserverMessage.Notify((ob) => ob.ReceiveMessage(message), targetObserver);
            return Task.CompletedTask;
        }
        /// <summary>
        /// 发送健康检查
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public Task SendHealthCheck(byte[] data, IEnumerable<IMessageObserver<TMessage>> targetObserver = null)
        {
            _ObserverMessage.Notify((ob) => ob.ReceiveHealthCheck(data), targetObserver);
            return Task.CompletedTask;
        }
        /// <summary>
        /// 判断某个监听者是否还存在
        /// </summary>
        /// <param name="observer"></param>
        /// <returns></returns>
        public Task<bool> ImAlive(IMessageObserver<TMessage> observer)
        {
            if (observer == null) return Task.FromResult(false);
            else
            {
                var result = _ObserverMessage.IsSubscribed(observer);
                return Task.FromResult(result);
            }
        }
        /// <summary>
        /// 判断某个监听者是否还存在
        /// </summary>
        /// <param name="observer"></param>
        /// <returns></returns>
        public Task<bool> ImAlive(IGrainObserver observer)
        {
            if (observer == null) return Task.FromResult(false);
            else
            {
                var result = _ObserverMessage.IsSubscribed(observer);
                return Task.FromResult(result);
            }
        }

        /// <summary>
        /// 订阅
        /// </summary>
        /// <param name="observer"></param>
        /// <returns></returns>
        public Task Subscribe(IMessageObserver<TMessage> observer)
        {
            if (!_ObserverMessage.IsSubscribed(observer)) _ObserverMessage.Subscribe(observer);
            return Task.CompletedTask;
        }
        /// <summary>
        /// 取消订阅
        /// </summary>
        /// <param name="observer"></param>
        /// <returns></returns>
        public Task UnSubscribe(IMessageObserver<TMessage> observer)
        {
            if (_ObserverMessage.IsSubscribed(observer)) _ObserverMessage.Unsubscribe(observer);
            return Task.CompletedTask;
        }
    }
}
